package tools

import (
	"bytes"
	"encoding/binary"
	"github.com/pierrec/lz4/v4"
	"regexp"
	"strings"
)

func PathCombine(parent, child string) string {
	if strings.HasSuffix(parent, "/") || strings.HasPrefix(child, "/") {
		return parent + child
	}
	return parent + "/" + child
}

func PathMatchesPattern(searchPattern, name string, ignoreCase bool) (bool, error) {
	if ignoreCase {
		searchPattern = "(?i)" + searchPattern
	}
	re, err := regexp.Compile(searchPattern)
	if err != nil {
		return false, err
	}
	return re.MatchString(name), nil
}

func IsZeroArray(arr []byte) bool {
	for i := 0; i < len(arr); i++ {
		if arr[i] != 0 {
			return false
		}
	}
	return true
}

func ArrayEquals(a, b []byte) bool {
	//if len(a) != len(b) {
	//	return false
	//}
	l := len(a)
	if l > len(b) {
		l = len(b)
	}
	for i := 0; i < l; i++ {
		if a[i] != b[i] {
			return false
		}
	}
	return true
}

func GetMasterKeyRevision(keyGeneration byte) byte {
	if keyGeneration == 0 {
		return 0
	}

	return keyGeneration - 1
}

func SliceLong(data []byte, offsetLongNum int32) []byte {
	offsetLongNum *= 8
	return data[offsetLongNum:]
}

func BinarySearchLong(data []byte, value int64) int32 {
	for i := 0; i < len(data); i += 8 {
		if uint64(value) == binary.LittleEndian.Uint64(data[i:]) {
			return int32(i)
		}
	}
	return -1
}

func Lz4Decompress(data []byte, out []byte) error {
	buffer := bytes.NewBuffer(out)
	writer := lz4.NewWriter(buffer)
	defer writer.Close()
	_, err := writer.Write(data)
	if err != nil {
		return err
	}
	return writer.Flush()
}

func DivideUp(value, divisor int64) int64 {
	return (value + divisor - 1) / divisor
}

func ReverseSlice(data []byte) {
	start := 0
	end := len(data) - 1
	for start < end {
		data[start], data[end] = data[end], data[start]
		start++
		end--
	}
}

func Utf8ZToString(data []byte) string {
	sb := strings.Builder{}
	for _, v := range data {
		if v != 0 {
			sb.WriteByte(v)
		}
	}
	return sb.String()
}

func BytesToIntLittleEndian(data []byte) int32 {
	return int32(binary.LittleEndian.Uint32(data))
}

func BytesToIntBigEndian(data []byte) int32 {
	return int32(binary.BigEndian.Uint32(data))
}
